//
//  CGLImageCache.h
//  UI26_综合(多线程_ Block_沙盒_MD5_通知中心)
//
//  Created by 李劲成 on 16/4/14.
//  Copyright © 2016年 ljc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "CGLWebImageCompat.h"
@interface CGLImageCache : NSObject

#pragma mark - CacheType 枚举 (缓存的类型)
typedef NS_ENUM(NSInteger, CGLImageCacheType) {
    /**
     * The image wasn't available the CGLWebImage caches, but was downloaded from the web.
     */
    CGLImageCacheTypeNone,
    /**
     * The image was obtained from the disk cache.
     */
    CGLImageCacheTypeDisk,
    /**
     * The image was obtained from the memory cache.
     */
    CGLImageCacheTypeMemory
};

#pragma mark - BLOCK类型
/** 查询完成 Block 回调 image , 缓存类型*/
typedef void(^CGLWebImageQueryCompletedBlock)(UIImage *image, CGLImageCacheType);

/** 检查缓存是否完成 Block 回调 BOOL 值 */
typedef void(^CGLWebImageCheckCacheCompletitionBlock)(BOOL isInCache);

/** 计算图片大小 Block, 回调文件数量, 总共的大小, in bytes. */
typedef void(^CGLWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);

#pragma mark - 属性
/** 是否进行解压 */
@property (nonatomic, assign) BOOL shouldDecompressImages;

/**  */
/**
 * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
 */
@property (nonatomic, assign) NSUInteger maxMemoryCost;

/** 最大缓存时间 */
@property (nonatomic, assign) NSUInteger maxMemoryAge;

/** 最大缓存大小 */
@property (nonatomic, assign) NSUInteger maxMemorySize;
/**
 * The maximum number of objects the cache should hold.
 */
@property (assign, nonatomic) NSUInteger maxMemoryCountLimit;
/**
 *  disable iCloud backup [defaults to YES]
 */
@property (assign, nonatomic) BOOL shouldDisableiCloud;

/**
 * use memory cache [defaults to YES]
 */
@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;




#pragma mark - 方法.
#pragma mark -- 单例
/** 单例 */
/**
 * Returns global shared cache instance
 *
 * @return CGLImageCache global instance
 */
+ (CGLImageCache *)sharedImageCache;

#pragma mark -- 路径
#pragma mark ---- 指定缓存路径
/** 指定缓存路径 */
/**
 * Init a new cache store with a specific namespace
 *
 * @param ns The namespace to use for this cache store
 */
- (id)initWithSpecificNamespace:(NSString *)nameSpace;
/**
 * Init a new cache store with a specific namespace and directory
 *
 * @param ns        The namespace to use for this cache store
 * @param directory Directory to cache disk images in
 */
- (id)initWithNamespace:(NSString *)nameSpace diskCacheDirectory:(NSString *)directory;

-(NSString *)makeDiskCachePath:(NSString*)fullNamespace;

#pragma mark ---- 添加只读路径
/**
 * Add a read-only cache path to search for images pre-cached by CGLImageCache
 * Useful if you want to bundle pre-loaded images with your app
 *
 * @param path The path to use for this read-only cache path
 */
- (void)addReadOnlyCachePath:(NSString *)path;

#pragma mark -- 存储图片
/**
 * Store an image into memory and disk cache at the given key.
 *
 * @param image The image to store
 * @param key   The unique image cache key, usually it's image absolute URL
 */
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;

/**
 * Store an image into memory and optionally disk cache at the given key.
 *
 * @param image  The image to store
 * @param key    The unique image cache key, usually it's image absolute URL
 * @param toDisk Store the image to disk cache if YES
 */
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
#pragma mark ---- 存储图片时是否重新计算图片
/**
 * Store an image into memory and optionally disk cache at the given key.
 *
 * @param image       The image to store
 * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage
 * @param imageData   The image data as returned by the server, this representation will be used for disk storage
 *                    instead of converting the given image object into a storable/compressed image format in order
 *                    to save quality and CPU
 * @param key         The unique image cache key, usually it's image absolute URL
 * @param toDisk      Store the image to disk cache if YES
 */
- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk;

#pragma mark -- 搜索本地磁盘.
#pragma mark ---- 异步
/**
 * Query the disk cache asynchronously.
 *
 * @param key The unique key used to store the wanted image
 */
- (NSOperation*)asynchronismQueryDiskCacheForKey:(NSString *)key done:(CGLWebImageQueryCompletedBlock)doneBlock;

#pragma mark ---- 同步
/**
 * Query the disk cache synchronously after checking the memory cache.
 *
 * @param key The unique key used to store the wanted image
 */
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
#pragma mark -- 搜索缓存
/**
 * Query the memory cache synchronously.
 *
 * @param key The unique key used to store the wanted image
 */
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;

#pragma mark -- 从 内存 和 硬盘缓存 删除图片
#pragma mark ---- 同步
/**
 * Remove the image from memory and disk cache synchronously
 *
 * @param key The unique image cache key
 */
- (void)removeImageForKey:(NSString *)key;

#pragma mark ---- 异步
/**
 * Remove the image from memory and disk cache asynchronously
 *
 * @param key             The unique image cache key
 * @param completion      An block that should be executed after the image has been removed (optional)
 */
- (void)removeImageForKey:(NSString *)key withCompletion:(CGLWebImageNoParamsBlock)completion;
/**
 * Remove the image from memory and optionally disk cache asynchronously
 *
 * @param key      The unique image cache key
 * @param fromDisk Also remove cache entry from disk if YES
 */
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
/**
 * Remove the image from memory and optionally disk cache asynchronously
 *
 * @param key             The unique image cache key
 * @param fromDisk        Also remove cache entry from disk if YES
 * @param completion      An block that should be executed after the image has been removed (optional)
 */
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(CGLWebImageNoParamsBlock)completion;

#pragma mark -- 清除
#pragma mark ----清除所有内存缓存
/**
 * Clear all memory cached images
 */
- (void)clearMemory;
#pragma mark ----清除硬盘缓存
/**
 * Clear all disk cached images. Non-blocking method - returns immediately.
 * @param completion    An block that should be executed after cache expiration completes (optional)
 */
- (void)clearDiskOnCompletion:(CGLWebImageNoParamsBlock)completion;
/**
 * Clear all disk cached images
 * @see clearDiskOnCompletion:
 */
- (void)clearDisk;

#pragma mark -- 清理
#pragma mark ---- 清理所有过期缓存
/**
 * Remove all expired cached image from disk. Non-blocking method - returns immediately.
 * @param completionBlock An block that should be executed after cache expiration completes (optional)
 */
- (void)cleanDiskWithCompletionBlock:(CGLWebImageNoParamsBlock)completionBlock;
/**
 * Remove all expired cached image from disk
 * @see cleanDiskWithCompletionBlock:
 */
- (void)cleanDisk;

#pragma mark -- 获取本地信息
#pragma mark ---- 获取本地已使用缓存大小
/**
 * Get the size used by the disk cache
 */
- (NSUInteger)getSize;
#pragma mark ---- 获取本地缓存图片数量
/**
 * Get the number of images in the disk cache
 */
- (NSUInteger)getDiskCount;
#pragma mark ---- 异步计算本地已使用缓存大小
/**
 * Asynchronously calculate the disk cache's size.
 */
- (void)calculateSizeWithCompletionBlock:(CGLWebImageCalculateSizeBlock)completionBlock;

#pragma mark ---- 检查图像是否已经存在磁盘缓存中
#pragma mark ------ 异步
/**
 *  Async check if image exists in disk cache already (does not load the image)
 *
 *  @param key             the key describing the url
 *  @param completionBlock the block to be executed when the check is done.
 *  @note the completion block will be always executed on the main queue
 */

- (void)diskImageExistsWithKey:(NSString *)key completion:(CGLWebImageCheckCacheCompletitionBlock)completionBlock;
#pragma mark ------ 同步
/**
 *  Check if image exists in disk cache already (does not load the image)
 *
 *  @param key the key describing the url
 *
 *  @return YES if an image exists for the given key
 */
- (BOOL)diskImageExistsWithKey:(NSString *)key;


#pragma mark ---- 获取指定的文件夹下, 指定的缓存路径
/**
 *  Get the cache path for a certain key (needs the cache path root folder)
 *
 *  @param key  the key (can be obtained from url using cacheKeyForURL)
 *  @param path the cache path root folder
 *
 *  @return the cache path
 */
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;
#pragma mark ---- 获取默认路径下, 指定的缓存路径
/**
 *  Get the default cache path for a certain key
 *
 *  @param key the key (can be obtained from url using cacheKeyForURL)
 *
 *  @return the default cache path
 */
- (NSString *)defaultCachePathForKey:(NSString *)key;
@end
